package com.papper.common.utils.tool;

import tk.mybatis.mapper.util.StringUtil;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * @Author:Lajiao
 * @Date:2014年8月19日
 * @Time:下午2:37:11
 * @Description:日期工具类
 */
public class DateTool {
	//一秒钟毫秒数
	public static final long SECOND_MS = 1000L;
	//一分钟毫秒数
	public static final long MINUTE_MS = 60000L;
	//一小时毫秒数
	public static final long HOUR_MS   = 3600000L;
	//一天毫秒数
	public static final long DAY_MS    = 86400000L;

	public static final String YYYYMMDD               = "yyyyMMdd";
	public static final String HHMM                   = "HHmm";
	public static final String TIME_BEGIN             = " 00:00:00";
	public static final String TIME_END               = " 23:59:59";
	public static final String MONTH_PATTERN          = "yyyy-MM";
	public static final String DEFAULT_PATTERN        = "yyyyMMdd";
	public static final String FULL_PATTERN           = "yyyyMMddHHmmss";
	public static final String FULL_STANDARD_PATTERN  = "yyyyMMdd HH:mm:ss";
	public static final String TRADITION_PATTERN      = "yyyy-MM-dd";
	public static final String FULL_TRADITION_PATTERN = "yyyy-MM-dd HH:mm:ss";


	/**
	 * 年
	 */
	public final static int YEAR = Calendar.YEAR;

	/**
	 * 月
	 */
	public final static int MONTH = Calendar.MONTH;

	/**
	 *
	 */
	public final static int WEEK = Calendar.DAY_OF_WEEK;

	/**
	 * 日
	 */
	public final static int DAY = Calendar.DATE;

	/**
	 * 时
	 */
	public final static int HOUR = Calendar.HOUR_OF_DAY;

	/**
	 * 分
	 */
	public final static int MINUTE = Calendar.MINUTE;

	/**
	 * 秒
	 */
	public final static int SECOND = Calendar.SECOND;

	/**
	 * 毫秒
	 */
	public final static int MILLISECOND = Calendar.MILLISECOND;

	/**
	 * 年累积天
	 */
	public final static int DAY_OF_YEAR = Calendar.DAY_OF_YEAR;

	/**
	 * 月累积天
	 */
	public final static int DAY_OF_MONTH = Calendar.DAY_OF_MONTH;

	protected final static ThreadLocal<SimpleDateFormat> LOCAL_YMDHMSS = new ThreadLocal<SimpleDateFormat>();
	protected final static ThreadLocal<SimpleDateFormat> LOCAL_YMDHMS  = new ThreadLocal<SimpleDateFormat>();
	protected final static ThreadLocal<SimpleDateFormat> LOCAL_YMD     = new ThreadLocal<SimpleDateFormat>();
	protected final static ThreadLocal<SimpleDateFormat> LOCAL_YM      = new ThreadLocal<SimpleDateFormat>();
	protected final static ThreadLocal<SimpleDateFormat> LOCAL_HMS     = new ThreadLocal<SimpleDateFormat>();

	/**
	 * 年:月:日 时:分:秒:毫秒
	 */
	public final static String FORMAT_YMD_HMSS = "yyyy-MM-dd HH:mm:ss:SSS";

	/**
	 * 年:月:日 时:分:秒
	 */
	public final static String FORMAT_YMD_HMS = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 年:月:日
	 */
	public final static String FORMAT_YMD = "yyyy-MM-dd";

	/**
	 * 年:月
	 */
	public final static String FORMAT_YM = "yyyy-MM";

	/**
	 * 时:分:秒
	 */
	public final static String FORMAT_HMS = "HH:mm:ss";

	/**
	 * 每个月最大的天数
	 */
	protected final static Map<Integer, Integer> MAX_DAY_MAP;

	/**
	 * UTC时区
	 */
	public static final TimeZone TIME_ZONE_UTC = TimeZone.getTimeZone("UTC");

	/**
	 * DateUtil 使用的默认时区
	 */
	private static TimeZone defaultTimeZone;

	static {
		defaultTimeZone = TimeZone.getDefault();
		MAX_DAY_MAP = new HashMap<>(12);
		MAX_DAY_MAP.put(1, 31);
		MAX_DAY_MAP.put(2, 29);
		MAX_DAY_MAP.put(3, 31);
		MAX_DAY_MAP.put(4, 30);
		MAX_DAY_MAP.put(5, 31);
		MAX_DAY_MAP.put(6, 30);
		MAX_DAY_MAP.put(7, 31);
		MAX_DAY_MAP.put(8, 31);
		MAX_DAY_MAP.put(9, 30);
		MAX_DAY_MAP.put(10, 31);
		MAX_DAY_MAP.put(11, 30);
		MAX_DAY_MAP.put(12, 31);
	}

	/**
	 * 2月
	 */
	protected final static int TWO_MONTH = 2;

	/**
	 * 最大的小时
	 */
	protected final static int MAX_HOUR = 23;

	/**
	 * 最大的分钟
	 */
	protected final static int MAX_MINUTE = 59;

	/**
	 * 最大的秒
	 */
	protected final static int MAX_SECOND = 59;

	/**
	 * 最大的毫秒
	 */
	protected final static int MAX_MILLISECOND = 999;

	/**
	 * 一周的毫秒数
	 */
	protected final static int MILLISECONDS_PER_WEEK = 7 * 24 * 60 * 60 * 1000;

	/**
	 * 一日的毫秒数
	 */
	protected final static int MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;

	/**
	 * 一小时的毫秒数
	 */
	protected final static int MILLISECONDS_PER_HOUR = 60 * 60 * 1000;

	/**
	 * 一分钟的毫秒数
	 */
	protected final static int MILLISECONDS_PER_MINUTE = 60 * 1000;

	/**
	 * 一秒钟的毫秒数
	 */
	protected final static int MILLISECONDS_PER_SECOND = 1000;

	/**
	 * 判断日期是否合法
	 *
	 * @param year  年
	 * @param month 月
	 * @param day   日
	 * @return 合法返回true 不合法false
	 */
	public static boolean isDateRational(int year, int month, int day) {
		return isDateRational(year, month, day, 0, 0, 0, 0);
	}

	/**
	 * 判断日期是否合法
	 *
	 * @param year        年
	 * @param month       月
	 * @param day         日
	 * @param hour        时
	 * @param minute      分
	 * @param second      秒
	 * @param millisecond 毫秒
	 * @return 合法返回true 不合法false
	 */
	public static boolean isDateRational(int year, int month, int day, int hour, int minute, int second, int millisecond) {
		if (year == 0 || month == 0 || day == 0) {
			return false;
		}
		boolean flag = hour >= 0 && hour <= MAX_HOUR && minute >= 0 && minute <= MAX_MINUTE && second >= 0 && second <= MAX_SECOND && millisecond >= 0 && millisecond <= MAX_MILLISECOND;
		if (!flag) {
			return false;
		}
		Integer maxDay = MAX_DAY_MAP.get(month);
		if (maxDay == null) {
			return false;
		}
		if (month == TWO_MONTH && isLeapYear(year)) {
			return day <= maxDay;
		} else {
			return day <= maxDay - 1;
		}
	}

	/**
	 * 判断是否为闰年
	 *
	 * @param year 年
	 * @return 是闰年返回true 不是返回false
	 */
	public static boolean isLeapYear(int year) {
		boolean flag = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
		return flag;
	}

	/**
	 * 获得现在时间的时间戳
	 * 性能低 System.currentTimeMillis();
	 *
	 * @return 时间戳
	 */
	public static long getTimeStamp() {
		return System.currentTimeMillis();
	}

	/**
	 * 获得现在时间 Date
	 *
	 * @return Date
	 */
	public static Date getNow() {
		return new Date();
	}

	/**
	 * 设置DateUtil类使用的时区
	 *
	 * @param timeZone 时区
	 */
	public static void setTimeZone(TimeZone timeZone) {
		if (timeZone != null) {
			defaultTimeZone = timeZone;
		}
	}

	/**
	 * 获得现在时间 Calendar
	 *
	 * @param timeZone 时区
	 * @return
	 */
	public static Calendar getCalendar(TimeZone timeZone) {
		return Calendar.getInstance(timeZone);
	}

	/**
	 * 获得现在时间 Calendar
	 *
	 * @return Calendar
	 */
	public static Calendar getCalendar() {
		return Calendar.getInstance();
	}

	/**
	 * 获得现在时间 String
	 * 格式：yyyy-MM-dd hh:mm:ss.SSS
	 *
	 * @return 字符串显示的时间
	 */
	public static String getNowStr() {
		return getNowStr(FORMAT_YMD_HMS);
	}

	/**
	 * 获得现在时间 String
	 *
	 * @param pattern 时间格式
	 * @return 字符串显示的时间
	 */
	public static String getNowStr(String pattern) {
		return formatDate(getNow(), pattern);
	}

	/**
	 * 获得Calendar对象的年或月等
	 *
	 * @param calendar Calendar对象
	 * @param field    获取的field
	 * @return filed对应的值
	 */
	public static int getTime(Calendar calendar, int field) {
		if (calendar == null) {
			return 0;
		}
		return calendar.get(field);
	}

	/**
	 * 获得一年中的年积
	 *
	 * @param calendar Calendar对象
	 * @param ofYear   年积标识
	 * @return 返回年积某某
	 */
	public static int getOfYear(Calendar calendar, double ofYear) {
		if (calendar == null) {
			return 0;
		}
		Calendar startYear  = getStartCalendar(calendar, YEAR);
		double   difference = (double) (calendar.getTimeInMillis() - startYear.getTimeInMillis()) / ofYear;
		return (int) Math.ceil(difference);
	}

	/**
	 * 获得Calendar的年
	 *
	 * @param calendar Calendar对象
	 * @return 年
	 */
	public static int getYear(Calendar calendar) {
		return getTime(calendar, YEAR);
	}

	/**
	 * 获得Calendar的月
	 *
	 * @param calendar Calendar对象
	 * @return 月
	 */
	public static int getMonth(Calendar calendar) {
		return getTime(calendar, MONTH) + 1;
	}

	/**
	 * 获得Calendar的属于周几
	 * 1为周一  7为周日
	 *
	 * @return 周几
	 */
	public static int getWeek(Calendar calendar) {
		int week = getTime(calendar, WEEK) - 1;
		return week == 0 ? 7 : week;
	}

	/**
	 * 获得Calendar的日
	 *
	 * @return 日
	 */
	public static int getDay(Calendar calendar) {
		return getTime(calendar, DAY);
	}

	/**
	 * 获得Calendar的小时
	 *
	 * @return 小时
	 */
	public static int getHour(Calendar calendar) {
		return getTime(calendar, HOUR);
	}

	/**
	 * 获得Calendar的分钟
	 *
	 * @return 分钟
	 */
	public static int getMinute(Calendar calendar) {
		return getTime(calendar, MINUTE);
	}

	/**
	 * 获得Calendar的秒
	 *
	 * @return 秒
	 */
	public static int getSecond(Calendar calendar) {
		return getTime(calendar, SECOND);
	}

	/**
	 * 获得Calendar的毫秒
	 *
	 * @return 毫秒
	 */
	public static int getMillisecond(Calendar calendar) {
		return getTime(calendar, MILLISECOND);
	}

	/**
	 * 获得年累积天
	 *
	 * @return 年累积天
	 */
	public static int getDayOfYear(Calendar calendar) {
		return getTime(calendar, DAY_OF_YEAR);
	}

	/**
	 * 获得月累积天
	 *
	 * @return 月累积天
	 */
	public static int getDayOfMonth(Calendar calendar) {
		return getTime(calendar, DAY_OF_MONTH);
	}

	/**
	 * 获取起始日期
	 * 跟现实世界一样的计时
	 *
	 * @param calendar Calendar对象
	 * @param field    获取的field
	 * @return 返回起始日期
	 */
	public static Calendar getStartCalendar(Calendar calendar, int field) {
		Calendar startCalendar = null;
		if (field == YEAR) {
			startCalendar = getCalendar(getYear(calendar), 1, 1);
		} else if (field == MONTH) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), 1);
		} else if (field == DAY) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar));
		} else if (field == HOUR) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar), getHour(calendar), 0, 0);
		} else if (field == MINUTE) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar), getHour(calendar), getMinute(calendar), 0);
		} else if (field == SECOND) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar), getHour(calendar), getMinute(calendar), getSecond(calendar));
		} else if (field == MILLISECOND) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar), getHour(calendar), getMinute(calendar), getSecond(calendar), getMillisecond(calendar));
		} else if (field == WEEK) {
			startCalendar = getCalendar(getYear(calendar), getMonth(calendar), getDay(calendar));
			startCalendar = offsetDate(startCalendar, DAY, 1 - getWeek(calendar));
		}
		return startCalendar;
	}

	/**
	 * 设置时间（年月日时分秒毫秒）
	 *
	 * @param year   年
	 * @param month  月
	 * @param day    日
	 * @param hour   时
	 * @param minute 分
	 * @param second 秒
	 * @return Calendar
	 */
	public static Calendar setCalendar(int year, int month, int day, int hour, int minute, int second) {
		Calendar calendar = getCalendar();
		calendar.set(year, month - 1, day, hour, minute, second);
		return calendar;
	}

	/**
	 * 设置时间（年月日）
	 *
	 * @param year  年
	 * @param month 月
	 * @param day   日
	 * @return Calendar
	 */
	public static Calendar setCalendar(int year, int month, int day) {
		Calendar calendar = getCalendar();
		calendar.set(year, month - 1, day);
		return calendar;
	}

	/**
	 * 通过时间戳获得Calendar对象
	 *
	 * @param timeStamp 时间戳
	 * @return Calendar对象
	 */
	public static Calendar getCalendar(long timeStamp) {
		return getCalendar(new Date(timeStamp));
	}

	/**
	 * 通过Date对象获得Calendar对象
	 *
	 * @param date Date对象
	 * @return Calendar对象
	 */
	public static Calendar getCalendar(Date date) {
		Calendar calendar = getCalendar();
		calendar.setTime(date);
		return calendar;
	}

	/**
	 * 设置时间（年月日时分秒毫秒）
	 *
	 * @param year        年
	 * @param month       月
	 * @param day         日
	 * @param hour        时
	 * @param minute      分
	 * @param second      秒
	 * @param millisecond 毫秒
	 * @return Calendar
	 */
	public static Calendar getCalendar(int year, int month, int day, int hour, int minute, int second, int millisecond) {
		Calendar calendar = getCalendar();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, millisecond);
		return calendar;
	}

	/**
	 * 设置时间（年月日）时分秒毫秒归零
	 *
	 * @param year  年
	 * @param month 月
	 * @param day   日
	 * @return Calendar
	 */
	public static Calendar getCalendar(int year, int month, int day) {
		return getCalendar(year, month, day, 0, 0, 0, 0);
	}

	/**
	 * 设置时间（年月日时分秒）毫秒归零
	 *
	 * @param year   年
	 * @param month  月
	 * @param day    日
	 * @param hour   时
	 * @param minute 分
	 * @param second 秒
	 * @return Calendar
	 */
	public static Calendar getCalendar(int year, int month, int day, int hour, int minute, int second) {
		return getCalendar(year, month, day, hour, minute, second, 0);
	}

	/**
	 * 偏移日期
	 * 整数就增加日期 负数就减少日期
	 *
	 * @param calendar Calendar对象
	 * @param field    偏移的对象 YEAR MONTH ...
	 * @param amount   偏移的数值
	 * @return Calendar对象
	 */
	public static Calendar offsetDate(Calendar calendar, int field, int amount) {
		if (calendar == null) {
			return null;
		}
		calendar.add(field, amount);
		return calendar;
	}

	/**
	 * 获得时间轴列表
	 * 例:假如需要获得最近24小时的时间轴列表则如下给参数
	 * getTimeAxis(DateUtil.getCalendar(), DateUtil.HOUR, 24, true);
	 *
	 * @param endCalendar 结束时间
	 * @param filed       需要偏移的字段 取值在DateUtil中 如DateUtil.HOUR
	 * @param amount      需要的偏移多长时间
	 * @param flag        是否保留结束时间
	 * @return 时间轴列表
	 */
	public static List<Calendar> getTimeAxis(Calendar endCalendar, int filed, int amount, boolean flag) {
		if (isNull(endCalendar)) {
			return null;
		}
		List<Calendar> list           = new ArrayList<>(amount);
		Calendar       newEndCalender = getStartCalendar(endCalendar, filed);
		int            offset         = amount;
		int            stepSize       = 1;
		if (filed == WEEK) {
			filed = DAY;
			stepSize = 7;
		}
		offset = stepSize * amount;
		if (flag) {
			offset = offset - stepSize;
		}
		Calendar startCalender = DateTool.offsetDate(newEndCalender, filed, -offset);

		long time = startCalender.getTimeInMillis();
		for (int i = 0; i < amount; i++) {
			Calendar calendar = getCalendar(time);
			offsetDate(calendar, filed, stepSize * i);
			list.add(calendar);
		}
		return list;
	}

	public static void main(String[] args) {
		List<Calendar> list = getTimeAxis(DateTool.getCalendar(), DateTool.WEEK, 24, true);
		for (Calendar c : list) {
			System.out.println(formatDate(c.getTime(), FORMAT_YMD_HMS));
		}
	}

	public static boolean isNull(Calendar... calendars) {
		for (Calendar calendar : calendars) {
			if (calendar == null) {
				return true;
			}
		}
		return false;
	}

	public static boolean isNotNull(Calendar... calendars) {
		for (Calendar calendar : calendars) {
			if (calendar == null) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 日期比较 大于并且小于
	 * comparisonCalendar > startCalendar && comparisonCalendar < endCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param startCalendar      开始日期
	 * @param endCalendar        结束日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherExceedAndLessThan(Calendar comparisonCalendar, Calendar startCalendar, Calendar endCalendar) {
		if (isNull(comparisonCalendar, startCalendar, endCalendar)) {
			return false;
		}
		return comparisonCalendar.after(startCalendar) && comparisonCalendar.before(endCalendar);
	}

	/**
	 * 日期比较 大于等于并且小于等于
	 * comparisonCalendar > startCalendar && comparisonCalendar < endCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param startCalendar      开始日期
	 * @param endCalendar        结束日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherExceedEqualsAndLessThanEquals(Calendar comparisonCalendar, Calendar startCalendar, Calendar endCalendar) {
		if (isNull(comparisonCalendar, startCalendar, endCalendar)) {
			return false;
		}
		return (comparisonCalendar.after(startCalendar) || comparisonCalendar.equals(startCalendar)) && (comparisonCalendar.before(endCalendar) || comparisonCalendar.equals(endCalendar));
	}

	/**
	 * 日期比较 大于
	 * comparisonCalendar > startCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param calendar           日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherExceed(Calendar comparisonCalendar, Calendar calendar) {
		if (isNull(comparisonCalendar, calendar)) {
			return false;
		}
		return comparisonCalendar.after(calendar);
	}

	/**
	 * 日期比较 大于等于
	 * comparisonCalendar > startCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param calendar           日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherExceedEquals(Calendar comparisonCalendar, Calendar calendar) {
		if (isNull(comparisonCalendar, calendar)) {
			return false;
		}
		return comparisonCalendar.after(calendar) || comparisonCalendar.equals(calendar);
	}

	/**
	 * 日期比较 小于
	 * comparisonCalendar < endCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param calendar           日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherLessThan(Calendar comparisonCalendar, Calendar calendar) {
		if (isNull(comparisonCalendar, calendar)) {
			return false;
		}
		return comparisonCalendar.before(calendar);
	}

	/**
	 * 日期比较 小于等于
	 * comparisonCalendar < endCalendar
	 *
	 * @param comparisonCalendar 比较的日期
	 * @param calendar           日期
	 * @return 符合条件为true 否则 false
	 */
	public static boolean whetherLessThanEquals(Calendar comparisonCalendar, Calendar calendar) {
		if (isNull(comparisonCalendar, calendar)) {
			return false;
		}
		return comparisonCalendar.before(calendar) || comparisonCalendar.equals(calendar);
	}

	/**
	 * 格式化时间
	 * 线程安全
	 *
	 * @param dateStr 时间字符串
	 * @param pattern 时间格式
	 * @return Date
	 */
	public static Date parse(String dateStr, String pattern) {
		if (dateStr == null || "".equals(dateStr) || pattern == null || "".equals(pattern)) {
			return null;
		}
		SimpleDateFormat simpleDateFormat = getSimpleDateFormat(pattern);
		try {
			return simpleDateFormat.parse(dateStr);
		} catch (ParseException e) {
			throw new RuntimeException("日期字符串与匹配字符串不相符", e);
		}
	}

	/**
	 * 获取存入ThreadLocal中的SimpleDateFormat对象 如果没有配置的则直接新建一个
	 *
	 * @param pattern 时间格式
	 * @return SimpleDateFormat对象
	 */
	public static SimpleDateFormat getSimpleDateFormat(String pattern) {
		ThreadLocal<SimpleDateFormat> local = null;
		if (FORMAT_YMD_HMSS.equals(pattern)) {
			local = LOCAL_YMDHMSS;
		} else if (FORMAT_YMD_HMS.equals(pattern)) {
			local = LOCAL_YMDHMS;
		} else if (FORMAT_YMD.equals(pattern)) {
			local = LOCAL_YMD;
		} else if (FORMAT_YM.equals(pattern)) {
			local = LOCAL_YM;
		} else if (FORMAT_HMS.equals(pattern)) {
			local = LOCAL_HMS;
		}
		SimpleDateFormat simpleDateFormat = null;
		if (local != null) {
			simpleDateFormat = local.get();
			if (simpleDateFormat == null) {
				simpleDateFormat = new SimpleDateFormat(pattern);
				local.set(simpleDateFormat);
			}
		} else {
			simpleDateFormat = new SimpleDateFormat(pattern);
		}
		simpleDateFormat.setTimeZone(defaultTimeZone);
		return simpleDateFormat;
	}

	public static String getShortNow() {
		return formatDate("yyyy-MM-dd");
	}

	public static String getDayBegin() {
		return formatDate("yyyy-MM-dd") + TIME_BEGIN;
	}

	public static String getDayEnd() {
		return formatDate("yyyy-MM-dd") + TIME_END;
	}

	public static Date getDayBegin(Date date) {
		return DateTool.parseDate(DateTool.formatDate(date, TRADITION_PATTERN + TIME_BEGIN), FULL_TRADITION_PATTERN);
	}

	public static Date getDayEnd(Date date) {
		return DateTool.parseDate(DateTool.formatDate(date, TRADITION_PATTERN + TIME_END), FULL_TRADITION_PATTERN);
	}

	public static String getTimeBykm() {
		return formatDate("H:mm");
	}

	public static String getMonth() {
		return formatDate("MM");
	}

	public static String getDay() {
		return formatDate("dd");
	}

	public static String formatDate(Date date) {
		return formatDate(date, "yyyyMMdd");
	}

	public static String formatDate(Date date, String format) {
		if ((null == date) || (StringUtil.isEmpty(format))) {
			return null;
		}
		try {
			return new SimpleDateFormat(format).format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String formatDate(String format) {
		return formatDate(new Date(), format);
	}

	public static Date parseDate(Long date) {
		return new Date(date);
	}

	public static Date parseDate(String date) {
		return parseDate(date, "yyyyMMdd", null);
	}

	public static Date parseDate(String date, String df) {
		return parseDate(date, df, null);
	}

	public static Date parseDate(String date, String df, Date defaultValue) {
		if ((date == null) || (StringUtil.isEmpty(df))) {
			return defaultValue;
		}

		SimpleDateFormat formatter = new SimpleDateFormat(df);
		try {
			return formatter.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return defaultValue;
	}

	public static Date currentDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		calendar.set(10, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		return new Date(calendar.getTimeInMillis());
	}

	public static Date getStartOfDate(Date date) {
		if (date == null) {
			return null;
		}
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);

		cal.set(11, 0);
		cal.set(12, 0);
		cal.set(13, 0);
		cal.set(14, 0);

		return new Date(cal.getTime().getTime());
	}

	public static Date getPreviousMonday() {
		Calendar cd = Calendar.getInstance();

		int  dayOfWeek = cd.get(7) - 1;
		Date date;
		if (dayOfWeek == 1) {
			date = addDays(cd.getTime(), -7);
		} else {
			date = addDays(cd.getTime(), -6 - dayOfWeek);
		}

		return getStartOfDate(date);
	}

	public static Date getMondayBefore4Week() {
		Calendar cd = Calendar.getInstance();

		int  dayOfWeek = cd.get(7) - 1;
		Date date;
		if (dayOfWeek == 1) {
			date = addDays(cd.getTime(), -28);
		} else {
			date = addDays(cd.getTime(), -27 - dayOfWeek);
		}

		return getStartOfDate(date);
	}

	public static Date getCurrentMonday() {
		Calendar cd = Calendar.getInstance();

		int  dayOfWeek = cd.get(7) - 1;
		Date date;
		if (dayOfWeek == 1) {
			date = cd.getTime();
		} else {
			date = addDays(cd.getTime(), 1 - dayOfWeek);
		}

		return getStartOfDate(date);
	}

	public static boolean beforeDay(Date date1, Date date2) {
		if (date1 == null) {
			return true;
		}
		return getStartOfDate(date1).before(getStartOfDate(date2));
	}

	public static boolean afterDay(Date date1, Date date2) {
		if (date1 == null) {
			return false;
		}
		return getStartOfDate(date1).after(getStartOfDate(date2));
	}

	public static Date addMonths(Date date, int months) {
		if (months == 0) {
			return date;
		}
		if (date == null) {
			return null;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(2, months);
		return cal.getTime();
	}

	public static Date addDays(Date date, int days) {
		if (days == 0) {
			return date;
		}
		if (date == null) {
			return null;
		}
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(5, days);

		return new Date(cal.getTime().getTime());
	}

	public static Date addMins(Date date, int mins) {
		if (mins == 0) {
			return date;
		}
		if (date == null) {
			return null;
		}
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(12, mins);

		return new Date(cal.getTime().getTime());
	}

	public static boolean isSameMonth(Date date1, Date date2) {
		if ((date1 == null) && (date2 == null)) {
			return true;
		}
		if ((date1 == null) || (date2 == null)) {
			return false;
		}
		Calendar cal1 = GregorianCalendar.getInstance();
		cal1.setTime(date1);
		Calendar cal2 = GregorianCalendar.getInstance();
		cal2.setTime(date2);
		return isSameMonth(cal1, cal2);
	}

	public static boolean isSameDay(Date date1, Date date2) {
		if ((date1 == null) && (date2 == null)) {
			return true;
		}
		if ((date1 == null) || (date2 == null)) {
			return false;
		}
		Calendar cal1 = GregorianCalendar.getInstance();
		cal1.setTime(date1);
		Calendar cal2 = GregorianCalendar.getInstance();
		cal2.setTime(date2);

		return (cal1.get(1) == cal2.get(1)) && (cal1.get(2) == cal2.get(2)) && (cal1.get(5) == cal2.get(5));
	}

	public static boolean isSameMonth(Calendar cal1, Calendar cal2) {
		if ((cal1 == null) && (cal2 == null)) {
			return true;
		}
		if ((cal1 == null) || (cal2 == null)) {
			return false;
		}
		return (cal1.get(1) == cal2.get(1)) && (cal1.get(2) == cal2.get(2));
	}

	public static Date getEndOfMonth(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		calendar.set(2, calendar.get(2) + 1);
		calendar.set(5, 0);

		calendar.set(11, 12);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		return new Date(calendar.getTimeInMillis());
	}

	public static Date getFirstOfMonth(Date date) {
		Date lastMonth = addMonths(date, -1);
		lastMonth = getEndOfMonth(lastMonth);
		return addDays(lastMonth, 1);
	}

	public static boolean inFormat(String sourceDate, String format) {
		if ((sourceDate == null) || (StringUtil.isEmpty(format))) {
			return false;
		}
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(format);
			dateFormat.setLenient(false);
			dateFormat.parse(sourceDate);
			return true;
		} catch (Exception e) {
		}
		return false;
	}

	public static String now() {
		return formatDate(new Date(), "yyyyMMddHHmmss");
	}

	public static String formatShortDateC(Date gstrDate) {
		if (gstrDate == null) {
			return null;
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");

		String pid = formatter.format(gstrDate);
		return pid;
	}

	public static String formatShort(String strDate) {
		String ret = "";
		if ((strDate != null) && (!"1900-01-01 00:00:00.0".equals(strDate)) && (strDate.indexOf("-") > 0)) {
			ret = strDate;
			if (ret.indexOf(" ") > -1) {
				ret = ret.substring(0, ret.indexOf(" "));
			}
		}
		return ret;
	}

	public static int getNumberOfSecondsBetween(double d1, double d2) {
		if ((d1 == 0.0D) || (d2 == 0.0D)) {
			return -1;
		}

		return (int) (Math.abs(d1 - d2) / 1000.0D);
	}

	public static int getNumberOfMonthsBetween(Date before, Date end) {
		if ((before == null) || (end == null)) {
			return -1;
		}
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(before);
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(end);
		return (cal2.get(1) - cal1.get(1)) * 12 + (cal2.get(2) - cal1.get(2));
	}

	public static long getNumberOfMinuteBetween(Date before, Date end) {
		if ((before == null) || (end == null)) {
			return -1L;
		}
		long millisec = end.getTime() - before.getTime();
		return millisec / 60000L;
	}

	public static long getNumberOfHoursBetween(Date before, Date end) {
		if ((before == null) || (end == null)) {
			return -1L;
		}
		long millisec = end.getTime() - before.getTime() + 1L;
		return millisec / 3600000L;
	}

	public static String formatMonthAndDay(Date srcDate) {
		return formatDate("MM月dd日");
	}

	public static long getNumberOfDaysBetween(Date before) {
		return getNumberOfDaysBetween(before, new Date());
	}

	public static long getNumberOfDaysBetween(Date before, Date end) {
		if ((before == null) || (end == null)) {
			return -1L;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(before);
		Calendar endCal = Calendar.getInstance();
		endCal.setTime(end);
		return getNumberOfDaysBetween(cal, endCal);
	}

	public static long getNumberOfDaysBetween(Calendar cal1, Calendar cal2) {
		if ((cal1 == null) || (cal2 == null)) {
			return -1L;
		}
		cal1.clear(14);
		cal1.clear(13);
		cal1.clear(12);
		cal1.clear(11);

		cal2.clear(14);
		cal2.clear(13);
		cal2.clear(12);
		cal2.clear(11);

		long elapsed = cal2.getTime().getTime() - cal1.getTime().getTime();
		return elapsed / 86400000L;
	}

	public static Calendar getCurrentCalendar() {
		return Calendar.getInstance();
	}

	public static Timestamp getCurrentDateTime() {
		return new Timestamp(System.currentTimeMillis());
	}

	public static Date getCurrentDate() {
		return new Date(System.currentTimeMillis());
	}

	public static final int getYear(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(1);
	}

	public static final int getYear(long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		return calendar.get(1);
	}

	public static final int getMonth(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(2) + 1;
	}

	public static final int getMonth(long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		return calendar.get(2) + 1;
	}

	public static final int getDate(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(5);
	}

	public static final int getDate(long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		return calendar.get(5);
	}

	public static final int getHour(Date date) {
		if (date == null) {
			return -1;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(11);
	}

	public static final int getHour(long millis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(millis);
		return calendar.get(11);
	}

	public static Date getDateByUrl(String url) {
		try {
			URLConnection uc = new URL(url).openConnection();
			uc.connect();
			return new Date(uc.getDate());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取当前日期是星期几<br>
	 *
	 * @param dt
	 * @return 当前日期是星期几
	 */
	public static String getWeekOfDate(Date dt) {
		String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
		Calendar cal      = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0) {
			w = 0;
		}
		return weekDays[w];
	}

	/**
	 * 判断是否同一秒
	 *
	 * @param oldTime
	 * @param newTime
	 * @return
	 */
	public static boolean sameSecond(long oldTime, long newTime) {
		Calendar calendarOld = Calendar.getInstance();
		calendarOld.setTimeInMillis(oldTime);
		Calendar calendarNew = Calendar.getInstance();
		calendarNew.setTimeInMillis(newTime);

		return calendarOld.get(13) == calendarNew.get(13);
	}

	public static String getCurrentTime(String format) {
		return new SimpleDateFormat(format).format(Calendar.getInstance().getTime());
	}

	public static String getCurrentYear() {
		return new SimpleDateFormat("yyyy").format(Calendar.getInstance().getTime());
	}

	public static String getCurrentMonth() {
		return new SimpleDateFormat("yyyyMM").format(Calendar.getInstance().getTime());
	}

	public static String getCurrentDay() {
		return new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
	}

	public static int getCurrentHour() {
		return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
	}

	public static String getCurrentTime() {
		return new SimpleDateFormat("yyMMddHHmmss").format(Calendar.getInstance().getTime());
	}

	public static String getTimeStrBetween(double d1, double d2) {
		if ((d1 == 0.0D) || (d2 == 0.0D)) {
			return "刚刚";
		}
		int delta = (int) (Math.abs(d1 - d2) / 1000.0D);
		if (delta < 1) {
			return "刚刚";
		} else if (delta < 60) {
			return delta + "秒前";
		} else if (delta < 3600) {
			return delta / 60 + "分钟前";
		} else if (delta < 3600 * 24) {
			return delta / 3600 + "小时前";
		} else {
			return formatDate(parseDate((long) d1), "yyyy-MM-dd HH:mm:ss");
		}
	}
}